// $Id: mem_op.c,v 1.1 2006-10-30 17:50:24 nicolasw Exp $
#include "mem_op.h"

#include <malloc.h>
#include <assert.h>
#include <stdio.h>
#include <string.h> /* Para strcmp */


static const char MALLOC_STR[] = "malloc";
static const char CALLOC_STR[] = "calloc";
static const char REALLOC_STR[] = "realloc";
static const char FREE_STR[] = "free";
static const unsigned int MAX_LINE = 1024;


struct mem_op_s // la estructura oculta
{
	op_code_t oc;
	void *rtag;
	size_t size;
	void *rtag_new;
};


mem_op_s *mo_create(void)
{
	mem_op_s *result = NULL;

	result = calloc(sizeof(mem_op_s),1);
	if (result) {
		result->oc = None;
		result->rtag = NULL;
		result->size = 0;
		result->rtag_new = NULL;
	}
	return result;
}


void mo_destroy(mem_op_s *this)
{
	assert(this);
	free(this); this = NULL;
}


bool mo_parse(mem_op_s *this, char* line)
{
	bool result = true;
	int nargs = 0;
	char key[MAX_LINE];

	assert(this && line);
	nargs = sscanf(line,"%s%*[ \t]%p%*[ \t]%d%*[ \t]%p\n", key, &(this->rtag), &(this->size), &(this->rtag_new));
	if (strcmp(key,MALLOC_STR)==0 && nargs==3) {
		this->oc = Malloc;
	} else if (strcmp(key,CALLOC_STR)==0 && nargs==3) {
		this->oc = Calloc;
	} else if (strcmp(key,REALLOC_STR)==0 && nargs==4) {
		this->oc = Realloc;
	} else if (strcmp(key,FREE_STR)==0 && nargs==2) {
		this->oc = Free;
	} else {
		result = false;
		this->oc = None;
	}
	
	return result;
}


op_code_t mo_code(const mem_op_s *this)
{
	assert(this);
	return this->oc;
}


void *mo_rtag(const mem_op_s *this)
{
	assert(this);
	return this->rtag;
}


size_t mo_size(const mem_op_s *this)
{
	assert(this);
	return this->size;
}


void *mo_rtag_new(const mem_op_s *this)
{
	assert(this);
	return this->rtag_new;
}


#ifdef DEBUG
void mo_printf(const mem_op_s *this)
{
	assert(this);
	switch (this->oc) {
		case None:
			printf("none");
			break;
		case Malloc:
			printf("malloc %p %i", this->rtag, this->size);
			break;
		case Calloc:
			printf("calloc %p %i", this->rtag, this->size);
			break;
		case Realloc:
			printf("realloc %p %i %p", this->rtag, this->size, this->rtag_new);
			break;
		case Free:
			printf("free %p", this->rtag);
			break;
		default:
			assert(false);
	}
	
}
#endif
